<!DOCTYPE HTML>
<html>

<head>
	<link rel="bookmark"  type="image/x-icon"  href="/img/logo_miccall.png"/>
	<link rel="shortcut icon" href="/img/logo_miccall.png">
	
			    <title>
    Ame雨
    </title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
    <link rel="stylesheet" href="/amelin-ting/css/mic_main.css" />
    <link rel="stylesheet" href="/amelin-ting/css/dropdownMenu.css" />
    <meta name="keywords" content="Ame雨" />
    
    	<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
	 
    <noscript>
        <link rel="stylesheet" href="/amelin-ting/css/noscript.css" />
    </noscript>
    <style type="text/css">
        body:before {
          content: ' ';
          position: fixed;
          top: 0;
          background: url('/amelin-ting/img/bg.jpg') center 0 no-repeat;
          right: 0;
          bottom: 0;
          left: 0;
          background-size: cover; 
        }
    </style>

			    
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script async type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


    <script src="/amelin-ting/js/jquery.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrollex.min.js"></script>
    <script src="/amelin-ting/js/jquery.scrolly.min.js"></script>
    <script src="/amelin-ting/js/skel.min.js"></script>
    <script src="/amelin-ting/js/util.js"></script>
    <script src="/amelin-ting/js/main.js"></script>
	
<meta name="generator" content="Hexo 5.4.0"></head>
    
		
<!-- Layouts -->



<!--  代码渲染  -->
<link rel="stylesheet" href="/css/prism_coy.css" />
<link rel="stylesheet" href="/css/typo.css" />
<!-- 文章页 -->
<body class="is-loading">
    <!-- Wrapper 外包 s-->
    <div id="wrapper" class="fade-in">
        <!-- Intro 头部显示 s -->
        <!-- Intro 头部显示 e -->
        <!-- Header 头部logo start -->
        <header id="header">
    <a href="/amelin-ting/" class="logo">Art Space</a>
</header>
        <!-- Nav 导航条 start -->
        <nav id="nav" class="special" >
            <ul class="menu links" >
			<!-- Homepage  主页  --> 
			<li >
	            <a href="/amelin-ting/" rel="nofollow">主页</a>
	        </li>
			<!-- categories_name  分类   --> 
	        
	        <li class="active">
	            <a href="#s1">分类</a>
	                    <ul class="submenu">
	                        <li>
	                        <a class="category-link" href="/amelin-ting/categories/Go/">Go</a></li><li><a class="category-link" href="/amelin-ting/categories/django/">django</a></li><li><a class="category-link" href="/amelin-ting/categories/drf/">drf</a></li><li><a class="category-link" href="/amelin-ting/categories/gin/">gin</a></li><li><a class="category-link" href="/amelin-ting/categories/go/">go</a></li><li><a class="category-link" href="/amelin-ting/categories/linux/">linux</a></li><li><a class="category-link" href="/amelin-ting/categories/mysql/">mysql</a></li><li><a class="category-link" href="/amelin-ting/categories/python/">python</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/">内网穿透</a></li><li><a class="category-link" href="/amelin-ting/categories/%E5%89%8D%E7%AB%AF/">前端</a>
	                    </ul>
	        </li>
	        
	        <!-- archives  归档   --> 
	        
	        
		        <!-- Pages 自定义   -->
		        
		        <li>
		            <a href="/about/" title="简历">
		                简历
		            </a>
		        </li>
		        
		        <li>
		            <a href="/group/" title="团队">
		                团队
		            </a>
		        </li>
		        
		        <li>
		            <a href="/gallery/" title="图库">
		                图库
		            </a>
		        </li>
		        
		        <li>
		            <a href="/tag/" title="标签">
		                标签
		            </a>
		        </li>
		        


            </ul>
            <!-- icons 图标   -->
			<ul class="icons">
                    
                    <li>
                        <a title="github" href="https://github.com/miccall" target="_blank" rel="noopener">
                            <i class="icon fa fa-github"></i>
                        </a>
                    </li>
                    
                    <li>
                        <a title="500px" href="http://500px.com" target="_blank" rel="noopener">
                            <i class="icon fa fa-500px"></i>
                        </a>
                    </li>
                    
			</ul>
</nav>

        <div id="main" >
            <div class ="post_page_title_img" style="height: 25rem;background-image: url(https://img0.baidu.com/it/u=3274377523,2702638189&amp;fm=26&amp;fmt=auto);background-position: center; background-repeat:no-repeat; background-size:cover;-moz-background-size:cover;overflow:hidden;" >
                <a href="#" style="padding: 4rem 4rem 2rem 4rem ;"><h2 >gin-脚手架</h2></a>
            </div>
            <!-- Post -->
            <div class="typo" style="padding: 3rem;">
                <h2 id="config-yaml"><a href="#config-yaml" class="headerlink" title="config.yaml"></a>config.yaml</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">name: <span class="string">&quot;bluebell&quot;</span></span><br><span class="line">mode: <span class="string">&quot;dev&quot;</span></span><br><span class="line">startTime: <span class="string">&quot;2020-09-18&quot;</span></span><br><span class="line">machineID: <span class="number">1</span></span><br><span class="line">port: <span class="number">8081</span></span><br><span class="line"></span><br><span class="line">logger:</span><br><span class="line">  level: <span class="string">&quot;debug&quot;</span></span><br><span class="line">  filename: <span class="string">&quot;blueBell.log&quot;</span></span><br><span class="line">  maxSize: <span class="number">200</span></span><br><span class="line">  maxAge: <span class="number">30</span></span><br><span class="line">  maxBackups: <span class="number">7</span></span><br><span class="line"></span><br><span class="line">mysql:</span><br><span class="line">  username: <span class="string">&quot;root&quot;</span></span><br><span class="line">  password: <span class="string">&quot;123456&quot;</span></span><br><span class="line">  database: <span class="string">&quot;car&quot;</span></span><br><span class="line">  host: <span class="string">&quot;127.0.0.1&quot;</span></span><br><span class="line">  port: <span class="number">3306</span></span><br><span class="line">  setMaxOpenConns: <span class="number">200</span></span><br><span class="line">  setMaxIdleConns: <span class="number">50</span></span><br></pre></td></tr></table></figure>

<h2 id="settings"><a href="#settings" class="headerlink" title="settings"></a>settings</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> settings</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">&quot;fmt&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="string">&quot;github.com/fsnotify/fsnotify&quot;</span></span><br><span class="line"><span class="string">&quot;github.com/spf13/viper&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Conf = <span class="built_in">new</span>(AppConfig) <span class="comment">// 把这些配置保存到一个变量</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> AppConfig <span class="keyword">struct</span> &#123;</span><br><span class="line">	Name        <span class="keyword">string</span>       <span class="string">`mapstructure:&quot;name&quot;`</span></span><br><span class="line">	Mode        <span class="keyword">string</span>       <span class="string">`mapstructure:&quot;mode&quot;`</span></span><br><span class="line">	StartTime   <span class="keyword">string</span>       <span class="string">`mapstructure:&quot;startTime&quot;`</span></span><br><span class="line">	Port        <span class="keyword">int</span>          <span class="string">`mapstructure:&quot;port&quot;`</span></span><br><span class="line">	MachineID   <span class="keyword">int64</span>        <span class="string">`mapstructure:&quot;machineID&quot;`</span></span><br><span class="line">	LogConfig   *LogConfig   <span class="string">`mapstructure:&quot;logger&quot;`</span></span><br><span class="line">	MysqlConfig *MysqlConfig <span class="string">`mapstructure:&quot;mysql&quot;`</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> LogConfig <span class="keyword">struct</span> &#123;</span><br><span class="line">	Level      <span class="keyword">string</span> <span class="string">`mapstructure:&quot;level&quot;`</span></span><br><span class="line">	FileName   <span class="keyword">string</span> <span class="string">`mapstructure:&quot;filename&quot;`</span></span><br><span class="line">	MaxSize    <span class="keyword">int</span>    <span class="string">`mapstructure:&quot;maxSize&quot;`</span></span><br><span class="line">	MaxAge     <span class="keyword">int</span>    <span class="string">`mapstructure:&quot;maxAge&quot;`</span></span><br><span class="line">	MaxBackups <span class="keyword">int</span>    <span class="string">`mapstructure:&quot;maxBackups&quot;`</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> MysqlConfig <span class="keyword">struct</span> &#123;</span><br><span class="line">	UserName        <span class="keyword">string</span> <span class="string">`mapstructure:&quot;username&quot;`</span></span><br><span class="line">	Password        <span class="keyword">string</span> <span class="string">`mapstructure:&quot;password&quot;`</span></span><br><span class="line">	DataBase        <span class="keyword">string</span> <span class="string">`mapstructure:&quot;database&quot;`</span></span><br><span class="line">	Host            <span class="keyword">string</span> <span class="string">`mapstructure:&quot;host&quot;`</span></span><br><span class="line">	Port            <span class="keyword">int64</span>  <span class="string">`mapstructure:&quot;port&quot;`</span></span><br><span class="line">	SetMaxOpenConns <span class="keyword">int</span>    <span class="string">`mapstructure:&quot;setMaxOpenConns&quot;`</span></span><br><span class="line">	SetMaxIdleConns <span class="keyword">int</span>    <span class="string">`mapstructure:&quot;setMaxIdleConns&quot;`</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Init 初始化配置文件</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Init</span><span class="params">()</span> <span class="params">(err error)</span></span> &#123;</span><br><span class="line">	<span class="comment">// 读取配置文件</span></span><br><span class="line">	viper.SetConfigName(<span class="string">&quot;config&quot;</span>)     <span class="comment">// 配置文件名称(无扩展名)</span></span><br><span class="line">	viper.AddConfigPath(<span class="string">&quot;./settings&quot;</span>) <span class="comment">// 查找配置文件所在的路径</span></span><br><span class="line">	err = viper.ReadInConfig()        <span class="comment">// 查找并读取配置文件</span></span><br><span class="line">	<span class="keyword">if</span> err != <span class="literal">nil</span> &#123;                   <span class="comment">// 处理读取配置文件的错误</span></span><br><span class="line">		<span class="built_in">panic</span>(fmt.Errorf(<span class="string">&quot;Fatal error config file: %s \n&quot;</span>, err))</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// 将读取的配置文件反序列化到配置变量Conf中</span></span><br><span class="line">	<span class="keyword">if</span> err = viper.Unmarshal(Conf); err != <span class="literal">nil</span> &#123;</span><br><span class="line">		fmt.Printf(<span class="string">&quot;viper.Unmarshal failed, err:%s&quot;</span>, err)</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// 监控配置文件的改变</span></span><br><span class="line">	viper.WatchConfig()</span><br><span class="line">	viper.OnConfigChange(<span class="function"><span class="keyword">func</span><span class="params">(in fsnotify.Event)</span></span> &#123;</span><br><span class="line">		<span class="comment">// 配置文件发生变更之后会调用的回调函数</span></span><br><span class="line">		fmt.Println(<span class="string">&quot;Config file changed:&quot;</span>, in.Name)</span><br><span class="line">	&#125;)</span><br><span class="line">	<span class="keyword">return</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="logger"><a href="#logger" class="headerlink" title="logger"></a>logger</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> logger</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;carFactory/settings&quot;</span></span><br><span class="line">	<span class="string">&quot;net&quot;</span></span><br><span class="line">	<span class="string">&quot;net/http&quot;</span></span><br><span class="line">	<span class="string">&quot;net/http/httputil&quot;</span></span><br><span class="line">	<span class="string">&quot;os&quot;</span></span><br><span class="line">	<span class="string">&quot;runtime/debug&quot;</span></span><br><span class="line">	<span class="string">&quot;strings&quot;</span></span><br><span class="line">	<span class="string">&quot;time&quot;</span></span><br><span class="line"></span><br><span class="line">	<span class="string">&quot;github.com/gin-gonic/gin&quot;</span></span><br><span class="line">	<span class="string">&quot;github.com/natefinch/lumberjack&quot;</span></span><br><span class="line">	<span class="string">&quot;go.uber.org/zap&quot;</span></span><br><span class="line">	<span class="string">&quot;go.uber.org/zap/zapcore&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Init 初始化Logger</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Init</span><span class="params">(cfg *settings.LogConfig, mode <span class="keyword">string</span>)</span> <span class="params">(err error)</span></span> &#123;</span><br><span class="line">	writeSyncer := getLogWriter(cfg.FileName, cfg.MaxSize, cfg.MaxBackups, cfg.MaxAge)</span><br><span class="line">	encoder := getEncoder()</span><br><span class="line">	<span class="keyword">var</span> l = <span class="built_in">new</span>(zapcore.Level)</span><br><span class="line">	err = l.UnmarshalText([]<span class="keyword">byte</span>(cfg.Level))</span><br><span class="line">	<span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">		<span class="keyword">return</span></span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">var</span> core zapcore.Core</span><br><span class="line">	<span class="keyword">if</span> mode == <span class="string">&quot;dev&quot;</span> &#123;</span><br><span class="line">		<span class="comment">// 进入开发模式，日志也要打印到命令行</span></span><br><span class="line">		consoleEnbcoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())</span><br><span class="line">		core = zapcore.NewTee(</span><br><span class="line">			zapcore.NewCore(encoder, writeSyncer, l),                                      <span class="comment">// 输出文件</span></span><br><span class="line">			zapcore.NewCore(consoleEnbcoder, zapcore.Lock(os.Stdout), zapcore.DebugLevel)) <span class="comment">// 输出到命令行</span></span><br><span class="line">	&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">		core = zapcore.NewCore(encoder, writeSyncer, l)</span><br><span class="line">	&#125;</span><br><span class="line">	lg := zap.New(core, zap.AddCaller())</span><br><span class="line">	zap.ReplaceGlobals(lg) <span class="comment">// 替换zap包中全局的logger实例，后续在其他包中只需使用zap.L()调用即可</span></span><br><span class="line">	<span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">getEncoder</span><span class="params">()</span> <span class="title">zapcore</span>.<span class="title">Encoder</span></span> &#123;</span><br><span class="line">	encoderConfig := zap.NewProductionEncoderConfig()</span><br><span class="line">	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder</span><br><span class="line">	encoderConfig.TimeKey = <span class="string">&quot;time&quot;</span></span><br><span class="line">	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder</span><br><span class="line">	encoderConfig.EncodeDuration = zapcore.SecondsDurationEncoder</span><br><span class="line">	encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder</span><br><span class="line">	<span class="keyword">return</span> zapcore.NewJSONEncoder(encoderConfig)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">getLogWriter</span><span class="params">(filename <span class="keyword">string</span>, maxSize, maxBackup, maxAge <span class="keyword">int</span>)</span> <span class="title">zapcore</span>.<span class="title">WriteSyncer</span></span> &#123;</span><br><span class="line">	lumberJackLogger := &amp;lumberjack.Logger&#123;</span><br><span class="line">		Filename:   filename,</span><br><span class="line">		MaxSize:    maxSize,</span><br><span class="line">		MaxBackups: maxBackup,</span><br><span class="line">		MaxAge:     maxAge,</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> zapcore.AddSync(lumberJackLogger)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// GinLogger 接收gin框架默认的日志</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GinLogger</span><span class="params">()</span> <span class="title">gin</span>.<span class="title">HandlerFunc</span></span> &#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">		start := time.Now()</span><br><span class="line">		path := c.Request.URL.Path</span><br><span class="line">		query := c.Request.URL.RawQuery</span><br><span class="line">		c.Next()</span><br><span class="line"></span><br><span class="line">		cost := time.Since(start)</span><br><span class="line">		zap.L().Info(path,</span><br><span class="line">			zap.Int(<span class="string">&quot;status&quot;</span>, c.Writer.Status()),</span><br><span class="line">			zap.String(<span class="string">&quot;method&quot;</span>, c.Request.Method),</span><br><span class="line">			zap.String(<span class="string">&quot;path&quot;</span>, path),</span><br><span class="line">			zap.String(<span class="string">&quot;query&quot;</span>, query),</span><br><span class="line">			zap.String(<span class="string">&quot;ip&quot;</span>, c.ClientIP()),</span><br><span class="line">			zap.String(<span class="string">&quot;user-agent&quot;</span>, c.Request.UserAgent()),</span><br><span class="line">			zap.String(<span class="string">&quot;errors&quot;</span>, c.Errors.ByType(gin.ErrorTypePrivate).String()),</span><br><span class="line">			zap.Duration(<span class="string">&quot;cost&quot;</span>, cost),</span><br><span class="line">		)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// GinRecovery recover掉项目可能出现的panic，并使用zap记录相关日志</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GinRecovery</span><span class="params">(stack <span class="keyword">bool</span>)</span> <span class="title">gin</span>.<span class="title">HandlerFunc</span></span> &#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">(c *gin.Context)</span></span> &#123;</span><br><span class="line">		<span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">			<span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span> &#123;</span><br><span class="line">				<span class="comment">// Check for a broken connection, as it is not really a</span></span><br><span class="line">				<span class="comment">// condition that warrants a panic stack trace.</span></span><br><span class="line">				<span class="keyword">var</span> brokenPipe <span class="keyword">bool</span></span><br><span class="line">				<span class="keyword">if</span> ne, ok := err.(*net.OpError); ok &#123;</span><br><span class="line">					<span class="keyword">if</span> se, ok := ne.Err.(*os.SyscallError); ok &#123;</span><br><span class="line">						<span class="keyword">if</span> strings.Contains(strings.ToLower(se.Error()), <span class="string">&quot;broken pipe&quot;</span>) || strings.Contains(strings.ToLower(se.Error()), <span class="string">&quot;connection reset by peer&quot;</span>) &#123;</span><br><span class="line">							brokenPipe = <span class="literal">true</span></span><br><span class="line">						&#125;</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line"></span><br><span class="line">				httpRequest, _ := httputil.DumpRequest(c.Request, <span class="literal">false</span>)</span><br><span class="line">				<span class="keyword">if</span> brokenPipe &#123;</span><br><span class="line">					zap.L().Error(c.Request.URL.Path,</span><br><span class="line">						zap.Any(<span class="string">&quot;error&quot;</span>, err),</span><br><span class="line">						zap.String(<span class="string">&quot;request&quot;</span>, <span class="keyword">string</span>(httpRequest)),</span><br><span class="line">					)</span><br><span class="line">					<span class="comment">// If the connection is dead, we can&#x27;t write a status to it.</span></span><br><span class="line">					c.Error(err.(error)) <span class="comment">// nolint: errcheck</span></span><br><span class="line">					c.Abort()</span><br><span class="line">					<span class="keyword">return</span></span><br><span class="line">				&#125;</span><br><span class="line"></span><br><span class="line">				<span class="keyword">if</span> stack &#123;</span><br><span class="line">					zap.L().Error(<span class="string">&quot;[Recovery from panic]&quot;</span>,</span><br><span class="line">						zap.Any(<span class="string">&quot;error&quot;</span>, err),</span><br><span class="line">						zap.String(<span class="string">&quot;request&quot;</span>, <span class="keyword">string</span>(httpRequest)),</span><br><span class="line">						zap.String(<span class="string">&quot;stack&quot;</span>, <span class="keyword">string</span>(debug.Stack())),</span><br><span class="line">					)</span><br><span class="line">				&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">					zap.L().Error(<span class="string">&quot;[Recovery from panic]&quot;</span>,</span><br><span class="line">						zap.Any(<span class="string">&quot;error&quot;</span>, err),</span><br><span class="line">						zap.String(<span class="string">&quot;request&quot;</span>, <span class="keyword">string</span>(httpRequest)),</span><br><span class="line">					)</span><br><span class="line">				&#125;</span><br><span class="line">				c.AbortWithStatus(http.StatusInternalServerError)</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;()</span><br><span class="line">		c.Next()</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="mysql"><a href="#mysql" class="headerlink" title="mysql"></a>mysql</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> mysql</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;carFactory/settings&quot;</span></span><br><span class="line">	<span class="string">&quot;fmt&quot;</span></span><br><span class="line"></span><br><span class="line">	<span class="string">&quot;go.uber.org/zap&quot;</span></span><br><span class="line"></span><br><span class="line">	_ <span class="string">&quot;github.com/go-sql-driver/mysql&quot;</span></span><br><span class="line">	<span class="string">&quot;github.com/jmoiron/sqlx&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> db *sqlx.DB</span><br><span class="line"></span><br><span class="line"><span class="comment">// Init 初始化mysql数据库</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Init</span><span class="params">(cfg *settings.MysqlConfig)</span> <span class="params">(err error)</span></span> &#123;</span><br><span class="line">	dsn := fmt.Sprintf(<span class="string">&quot;%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&amp;parseTime=True&quot;</span>,</span><br><span class="line">		cfg.UserName,</span><br><span class="line">		cfg.Password,</span><br><span class="line">		cfg.Host,</span><br><span class="line">		cfg.Port,</span><br><span class="line">		cfg.DataBase)</span><br><span class="line">	<span class="comment">// 也可以使用MustConnect连接不成功就panic</span></span><br><span class="line">	db, err = sqlx.Connect(<span class="string">&quot;mysql&quot;</span>, dsn)</span><br><span class="line">	<span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">		fmt.Println(<span class="string">&quot;connect DB failed, err&quot;</span>, zap.Error(err))</span><br><span class="line">		<span class="keyword">return</span></span><br><span class="line">	&#125;</span><br><span class="line">	db.SetMaxOpenConns(cfg.SetMaxOpenConns)</span><br><span class="line">	db.SetMaxIdleConns(cfg.SetMaxIdleConns)</span><br><span class="line">	<span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Close 定义一个关闭mysql的向外暴露的接口</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Close</span><span class="params">()</span> <span class="params">(err error)</span></span> &#123;</span><br><span class="line">	err = db.Close()</span><br><span class="line">	<span class="keyword">return</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="main"><a href="#main" class="headerlink" title="main"></a>main</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;carFactory/controller&quot;</span></span><br><span class="line">	<span class="string">&quot;carFactory/dao/mysql&quot;</span></span><br><span class="line">	<span class="string">&quot;carFactory/logger&quot;</span></span><br><span class="line">	<span class="string">&quot;carFactory/pkg/snowflake&quot;</span></span><br><span class="line">	<span class="string">&quot;carFactory/routes&quot;</span></span><br><span class="line">	<span class="string">&quot;carFactory/settings&quot;</span></span><br><span class="line">	<span class="string">&quot;context&quot;</span></span><br><span class="line">	<span class="string">&quot;fmt&quot;</span></span><br><span class="line">	<span class="string">&quot;log&quot;</span></span><br><span class="line">	<span class="string">&quot;net/http&quot;</span></span><br><span class="line">	<span class="string">&quot;os&quot;</span></span><br><span class="line">	<span class="string">&quot;os/signal&quot;</span></span><br><span class="line">	<span class="string">&quot;syscall&quot;</span></span><br><span class="line">	<span class="string">&quot;time&quot;</span></span><br><span class="line"></span><br><span class="line">	<span class="string">&quot;go.uber.org/zap&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	<span class="comment">// 1. 加载配置文件</span></span><br><span class="line">	<span class="keyword">if</span> err := settings.Init(); err != <span class="literal">nil</span> &#123;</span><br><span class="line">		zap.L().Debug(<span class="string">&quot;Main settings.Init failed&quot;</span>)</span><br><span class="line">		<span class="keyword">return</span></span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// 2. 初始化日志</span></span><br><span class="line">	<span class="keyword">if</span> err := logger.Init(settings.Conf.LogConfig, settings.Conf.Mode); err != <span class="literal">nil</span> &#123;</span><br><span class="line">		zap.L().Debug(<span class="string">&quot;Main logger.Init failed&quot;</span>)</span><br><span class="line">		<span class="keyword">return</span></span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">defer</span> zap.L().Sync()</span><br><span class="line">	<span class="comment">// 3. 初始化mysql</span></span><br><span class="line">	<span class="keyword">if</span> err := mysql.Init(settings.Conf.MysqlConfig); err != <span class="literal">nil</span> &#123;</span><br><span class="line">		zap.L().Debug(<span class="string">&quot;Main mysql.Init failed&quot;</span>)</span><br><span class="line">		<span class="keyword">return</span></span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">defer</span> mysql.Close()</span><br><span class="line">	<span class="comment">// 4. 配置路由</span></span><br><span class="line">	r := routes.Init()</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 5. 启动服务(优雅关机)</span></span><br><span class="line">	r.Run()</span><br><span class="line"></span><br><span class="line">	srv := &amp;http.Server&#123;</span><br><span class="line">		Addr:    <span class="string">&quot;:8080&quot;</span>,</span><br><span class="line">		Handler: r,</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="comment">// 开启一个goroutine启动服务</span></span><br><span class="line">		<span class="keyword">if</span> err := srv.ListenAndServe(); err != <span class="literal">nil</span> &amp;&amp; err != http.ErrServerClosed &#123;</span><br><span class="line">			log.Fatalf(<span class="string">&quot;listen: %s\n&quot;</span>, err)</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	<span class="comment">// 等待中断信号来优雅地关闭服务器，为关闭服务器操作设置一个5秒的超时</span></span><br><span class="line">	quit := <span class="built_in">make</span>(<span class="keyword">chan</span> os.Signal, <span class="number">1</span>) <span class="comment">// 创建一个接收信号的通道</span></span><br><span class="line">	<span class="comment">// kill 默认会发送 syscall.SIGTERM 信号</span></span><br><span class="line">	<span class="comment">// kill -2 发送 syscall.SIGINT 信号，我们常用的Ctrl+C就是触发系统SIGINT信号</span></span><br><span class="line">	<span class="comment">// kill -9 发送 syscall.SIGKILL 信号，但是不能被捕获，所以不需要添加它</span></span><br><span class="line">	<span class="comment">// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信号转发给quit</span></span><br><span class="line">	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <span class="comment">// 此处不会阻塞</span></span><br><span class="line">	&lt;-quit                                               <span class="comment">// 阻塞在此，当接收到上述两种信号时才会往下执行</span></span><br><span class="line">	log.Println(<span class="string">&quot;Shutdown Server ...&quot;</span>)</span><br><span class="line">	<span class="comment">// 创建一个5秒超时的context</span></span><br><span class="line">	ctx, cancel := context.WithTimeout(context.Background(), <span class="number">5</span>*time.Second)</span><br><span class="line">	<span class="keyword">defer</span> cancel()</span><br><span class="line">	<span class="comment">// 5秒内优雅关闭服务（将未处理完的请求处理完再关闭服务），超过5秒就超时退出</span></span><br><span class="line">	<span class="keyword">if</span> err := srv.Shutdown(ctx); err != <span class="literal">nil</span> &#123;</span><br><span class="line">		log.Fatal(<span class="string">&quot;Server Shutdown: &quot;</span>, err)</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	log.Println(<span class="string">&quot;Server exiting&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="air-conf"><a href="#air-conf" class="headerlink" title=".air.conf"></a>.air.conf</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"># [Air](https:<span class="comment">//github.com/cosmtrek/air) TOML 格式的配置文件</span></span><br><span class="line"></span><br><span class="line"># 工作目录</span><br><span class="line"># 使用 . 或绝对路径，请注意 <span class="string">`tmp_dir`</span> 目录必须在 <span class="string">`root`</span> 目录下</span><br><span class="line">root = <span class="string">&quot;.&quot;</span></span><br><span class="line">tmp_dir = <span class="string">&quot;tmp&quot;</span></span><br><span class="line"></span><br><span class="line">[build]</span><br><span class="line"># 只需要写你平常编译使用的shell命令。你也可以使用 <span class="string">`make`</span></span><br><span class="line"># Windows平台示例: cmd = <span class="string">&quot;go build -o tmp\main.exe .&quot;</span></span><br><span class="line">cmd = <span class="string">&quot;go build -o ./tmp/main .&quot;</span></span><br><span class="line"># 由<span class="string">`cmd`</span>命令得到的二进制文件名</span><br><span class="line"># Windows平台示例：bin = <span class="string">&quot;tmp\main.exe&quot;</span></span><br><span class="line">bin = <span class="string">&quot;tmp/main&quot;</span></span><br><span class="line"># 自定义执行程序的命令，可以添加额外的编译标识例如添加 GIN_MODE=release</span><br><span class="line"># Windows平台示例：full_bin = <span class="string">&quot;tmp\main.exe&quot;</span></span><br><span class="line">full_bin = <span class="string">&quot;APP_ENV=dev APP_USER=air ./tmp/main&quot;</span></span><br><span class="line"># 监听以下文件扩展名的文件.</span><br><span class="line">include_ext = [<span class="string">&quot;go&quot;</span>, <span class="string">&quot;tpl&quot;</span>, <span class="string">&quot;tmpl&quot;</span>, <span class="string">&quot;html&quot;</span>]</span><br><span class="line"># 忽略这些文件扩展名或目录</span><br><span class="line">exclude_dir = [<span class="string">&quot;assets&quot;</span>, <span class="string">&quot;tmp&quot;</span>, <span class="string">&quot;vendor&quot;</span>, <span class="string">&quot;frontend/node_modules&quot;</span>]</span><br><span class="line"># 监听以下指定目录的文件</span><br><span class="line">include_dir = []</span><br><span class="line"># 排除以下文件</span><br><span class="line">exclude_file = []</span><br><span class="line"># 如果文件更改过于频繁，则没有必要在每次更改时都触发构建。可以设置触发构建的延迟时间</span><br><span class="line">delay = <span class="number">1000</span> # ms</span><br><span class="line"># 发生构建错误时，停止运行旧的二进制文件。</span><br><span class="line">stop_on_error = <span class="literal">true</span></span><br><span class="line"># air的日志文件名，该日志文件放置在你的<span class="string">`tmp_dir`</span>中</span><br><span class="line">log = <span class="string">&quot;air_errors.log&quot;</span></span><br><span class="line"></span><br><span class="line">[log]</span><br><span class="line"># 显示日志时间</span><br><span class="line">time = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line">[color]</span><br><span class="line"># 自定义每个部分显示的颜色。如果找不到颜色，使用原始的应用程序日志。</span><br><span class="line">main = <span class="string">&quot;magenta&quot;</span></span><br><span class="line">watcher = <span class="string">&quot;cyan&quot;</span></span><br><span class="line">build = <span class="string">&quot;yellow&quot;</span></span><br><span class="line">runner = <span class="string">&quot;green&quot;</span></span><br><span class="line"></span><br><span class="line">[misc]</span><br><span class="line"># 退出时删除tmp目录</span><br><span class="line">clean_on_exit = <span class="literal">true</span></span><br></pre></td></tr></table></figure>

<h2 id="code"><a href="#code" class="headerlink" title="code"></a>code</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> myResponseCode</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> ResCode <span class="keyword">int64</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义各种报错的响应码</span></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line">	CodeSuccess ResCode = <span class="number">100</span> + <span class="literal">iota</span></span><br><span class="line">	CodeInvalidParam</span><br><span class="line">	CodeUserExist</span><br><span class="line">	CodeUserNotExist</span><br><span class="line">	CodeInvalidPassword</span><br><span class="line">	CodeServerBusy</span><br><span class="line">	CodeNeedLogin</span><br><span class="line">	CodeInvalidToken</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 用一个大map收集起来</span></span><br><span class="line"><span class="keyword">var</span> codeMsgMap = <span class="keyword">map</span>[ResCode]<span class="keyword">string</span>&#123;</span><br><span class="line">	CodeSuccess:         <span class="string">&quot;success&quot;</span>,</span><br><span class="line">	CodeInvalidParam:    <span class="string">&quot;无效的参数&quot;</span>,</span><br><span class="line">	CodeUserExist:       <span class="string">&quot;用户名不存在&quot;</span>,</span><br><span class="line">	CodeUserNotExist:    <span class="string">&quot;密码不存在&quot;</span>,</span><br><span class="line">	CodeInvalidPassword: <span class="string">&quot;无效的密码&quot;</span>,</span><br><span class="line">	CodeServerBusy:      <span class="string">&quot;服务繁忙&quot;</span>,</span><br><span class="line">	CodeNeedLogin:       <span class="string">&quot;需要登录&quot;</span>,</span><br><span class="line">	CodeInvalidToken:    <span class="string">&quot;无效的token&quot;</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(r ResCode)</span> <span class="title">Msg</span><span class="params">()</span> <span class="title">string</span></span> &#123;</span><br><span class="line">	msg, ok := codeMsgMap[r]</span><br><span class="line">	<span class="keyword">if</span> !ok &#123;</span><br><span class="line">		msg = codeMsgMap[CodeServerBusy]</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> msg</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="response"><a href="#response" class="headerlink" title="response"></a>response</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> myResponseCode</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;net/http&quot;</span></span><br><span class="line"></span><br><span class="line">	<span class="string">&quot;github.com/gin-gonic/gin&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> ResponseData <span class="keyword">struct</span> &#123;</span><br><span class="line">	Code ResCode</span><br><span class="line">	Msg  <span class="keyword">interface</span>&#123;&#125;</span><br><span class="line">	Data <span class="keyword">interface</span>&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">ResponseError</span><span class="params">(c *gin.Context, code ResCode)</span></span> &#123;</span><br><span class="line">	c.JSON(http.StatusOK, &amp;ResponseData&#123;</span><br><span class="line">		Code: code,</span><br><span class="line">		Msg:  code.Msg(),</span><br><span class="line">		Data: <span class="literal">nil</span>,</span><br><span class="line">	&#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">ResponseSuccess</span><span class="params">(c *gin.Context, data <span class="keyword">interface</span>&#123;&#125;)</span></span> &#123;</span><br><span class="line">	c.JSON(http.StatusOK, &amp;ResponseData&#123;</span><br><span class="line">		Code: CodeSuccess,</span><br><span class="line">		Msg:  CodeSuccess.Msg(),</span><br><span class="line">		Data: data,</span><br><span class="line">	&#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">ResponseErrorWithMsg</span><span class="params">(c *gin.Context, code ResCode, msg <span class="keyword">interface</span>&#123;&#125;)</span></span> &#123;</span><br><span class="line">	c.JSON(http.StatusOK, &amp;ResponseData&#123;</span><br><span class="line">		Code: code,</span><br><span class="line">		Msg:  msg,</span><br><span class="line">		Data: <span class="literal">nil</span>,</span><br><span class="line">	&#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


            </div>

            <!-- Post Comments -->
            
    <!-- 使用 DISQUS_CLICK -->
<div id="disqus-comment">
    <div id="disqus_thread"></div>

<!-- add animation -->
<style>
	.disqus_click_btn {
            line-height: 30px;
            margin: 0;
            min-width: 50px;
            padding: 0 14px;
            display: inline-block;
            font-family: "Roboto", "Helvetica", "Arial", sans-serif;
            font-size: 14px;
            font-weight: 400;
            text-transform: uppercase;
            letter-spacing: 0;
            overflow: hidden;
            will-change: box-shadow;
            transition: box-shadow .2s cubic-bezier(.4, 0, 1, 1), background-color .2s cubic-bezier(.4, 0, .2, 1), color .2s cubic-bezier(.4, 0, .2, 1);
            outline: 0;
            cursor: pointer;
            text-decoration: none;
            text-align: center;
            vertical-align: middle;
            border: 0;
            background: rgba(158, 158, 158, .2);
            box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
            color: #fff;
            background-color: #7EC0EE;
            text-shadow: 0
        }
</style>
	
<div class="btn_click_load" id="disqus_bt"> 
    <button class="disqus_click_btn">点击查看评论</button>
</div>

<!--
<script type="text/javascript">
$('.btn_click_load').click(function() {
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'http-miccall-tech'; // required: replace example with your forum shortname

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
      var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
      dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();

    document.getElementById('disqus_bt').style.display = "none";
});
</script>
-->
<script type="text/javascript">
    var disqus_config = function () {
        this.page.url = 'https://gitee.com/AmeX/amelin-ting.git/2020/07/13/Go---gin---%E8%84%9A%E6%89%8B%E6%9E%B6/';  // Replace PAGE_URL with your page's canonical URL variable
        this.page.identifier = 'https://gitee.com/AmeX/amelin-ting.git/2020/07/13/Go---gin---%E8%84%9A%E6%89%8B%E6%9E%B6/'; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
    };
</script>

<script type="text/javascript">
    $('.btn_click_load').click(function() {  //click to load comments
        (function() { // DON'T EDIT BELOW THIS LINE
            var d = document;
            var s = d.createElement('script');
            s.src = '//http-miccall-tech.disqus.com/embed.js';
            s.setAttribute('data-timestamp', + new Date());
            (d.head || d.body).appendChild(s);
        })();
        $('.btn_click_load').css('display','none');
    });
</script>
</div>
<style>
    #disqus-comment{
        background-color: #eee;
        padding: 2pc;
    }
</style>


        </div>
        <!-- Copyright 版权 start -->
                <div id="copyright">
            <ul>
                <li>&copy;Powered By <a target="_blank" rel="noopener" href="https://hexo.io/zh-cn/" style="border-bottom: none;">hexo</a></li>
                <li>Design: <a target="_blank" rel="noopener" href="http://miccall.tech " style="border-bottom: none;">miccall</a></li>
            </ul>
            
                <span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
			
        </div>
    </div>
</body>



 	
</html>
